using IQIGame.Onigao.GamePlay;
using LFloatMath.Math;

namespace IQIGame.Onigao.Logic
{
    public interface IFormulaOperand
    {
        EFormulaOperandType opType { get; }
        void Reset();
        bool parseByFormula { get; set; }
    }

    public abstract class TFormulaOperand<T> : IFormulaOperand
    {
        public abstract EFormulaOperandType opType { get; }
        public bool parseByFormula { get; set; }
        public bool active { get; set; }

        public virtual void Reset()
        {
            this.value = default;
        }

        protected T value;

        public abstract T GetValue(IFormulaObject rSelf, IFormulaObject rTarget);

        public virtual void SetValue(T value)
        {
            this.value = value;
        }

        public void SetParam(object param1 = null, object param2 = null, object param3 = null)
        {
            this.Set(param1);
            this.Set(param2);
            this.Set(param3);
        }

        protected virtual void Set(object param)
        {
        }

        public override string ToString()
        {
            return this.value.ToString();
        }
    }

    public class FormulaOperandNum : TFormulaOperand<LFloat>
    {
        public override EFormulaOperandType opType => EFormulaOperandType.Num;

        public override LFloat GetValue(IFormulaObject rSelf, IFormulaObject rTarget)
        {
            return value;
        }
    }

    public class FormulaOperandBool : TFormulaOperand<bool>
    {
        public override EFormulaOperandType opType => EFormulaOperandType.Bool;

        public override bool GetValue(IFormulaObject rSelf, IFormulaObject rTarget)
        {
            return value;
        }
    }

    public class FormulaOperandDynamic : TFormulaOperand<int>
    {
        public override EFormulaOperandType opType => EFormulaOperandType.DynamicIndex;

        public override int GetValue(IFormulaObject rSelf, IFormulaObject rTarget)
        {
            return value;
        }
    }

    // public class FormulaOperandStr : TFormulaOperand<string>
    // {
    //     public override EFormulaOperandType opType => EFormulaOperandType.String;
    //     public override void Reset()
    //     {
    //         this.value = string.Empty;
    //     }
    // }
    //
    // public class FormulaOperandObj : TFormulaOperand<object>
    // {
    //     public override EFormulaOperandType opType => EFormulaOperandType.Object;
    //     public override void Reset()
    //     {
    //         this.value = null;
    //     }
    // }

    public enum EFormulaOperandType
    {
        None,
        Num,
        Bool,
        Attr,
        DynamicIndex,
        String,
        Object,
    }
}